Cel: Celem zadania jest wykzazanie się umiejętnościami rozumienia i analizy danych w formie szeregu czasowego.
import urllib.request
import zipfile
import os
import pandas as pd
import plotly.express as px
import datetime
import matplotlib.pyplot as plt
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sn
SMALL_SIZE = 8
MEDIUM_SIZE = 10
BIGGER_SIZE = 30
plt.rc('font', size=BIGGER_SIZE)
plt.rc('axes', titlesize=BIGGER_SIZE)
plt.rc('axes', labelsize=BIGGER_SIZE)
plt.rc('xtick', labelsize=BIGGER_SIZE)
plt.rc('ytick', labelsize=BIGGER_SIZE)
plt.rc('legend', fontsize=BIGGER_SIZE)
plt.rc('figure', titlesize=BIGGER_SIZE)
URL = "https://archive.ics.uci.edu/ml/machine-learning-databases/00360/AirQualityUCI.zip"
FILE_NAME = "AirQualityUCI.zip"
DATASET_NAME = "AirQualityUCI.xlsx"
urllib.request.urlretrieve(URL, FILE_NAME)
if not os.path.exists(DATASET_NAME):
with zipfile.ZipFile(FILE_NAME, 'r') as zip_ref:
zip_ref.extractall(".")
df = pd.read_excel(DATASET_NAME)
df = df.loc[:, ~df.columns.str.contains('^Unnamed')]
df_date = df.groupby(by="Date").mean().round(2)
df_date['Month_year'] = pd.DatetimeIndex(df_date.index).strftime('%Y-%m')
df_date["Day"] = pd.DatetimeIndex(df_date.index).strftime('%d').astype(int).to_list()
df_date
| CO(GT) | PT08.S1(CO) | NMHC(GT) | C6H6(GT) | PT08.S2(NMHC) | NOx(GT) | PT08.S3(NOx) | NO2(GT) | PT08.S4(NO2) | PT08.S5(O3) | T | RH | AH | Month_year | Day | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Date | |||||||||||||||
| 2004-03-10 | 1.97 | 1316.50 | 86.50 | 8.46 | 912.25 | 132.00 | 1167.25 | 108.83 | 1545.33 | 1096.04 | 12.02 | 54.88 | 0.77 | 2004-03 | 10 |
| 2004-03-11 | -6.19 | 1244.06 | 104.50 | 7.99 | 851.80 | 130.04 | 1277.19 | 87.38 | 1522.70 | 885.03 | 9.83 | 64.07 | 0.78 | 2004-03 | 11 |
| 2004-03-12 | -14.10 | 1281.56 | 141.50 | 12.13 | 1008.23 | 142.58 | 1101.72 | 89.92 | 1627.22 | 1084.22 | 11.29 | 51.11 | 0.66 | 2004-03 | 12 |
| 2004-03-13 | -5.75 | 1330.56 | 139.25 | 10.92 | 992.82 | 168.42 | 993.16 | 105.58 | 1595.62 | 1245.78 | 12.87 | 51.53 | 0.73 | 2004-03 | 13 |
| 2004-03-14 | -5.97 | 1360.93 | 116.96 | 9.63 | 943.85 | 132.17 | 1001.10 | 97.46 | 1602.19 | 1234.18 | 16.02 | 48.84 | 0.85 | 2004-03 | 14 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 2005-03-31 | 1.39 | 1007.99 | -200.00 | 5.23 | 749.30 | 184.99 | 795.48 | 100.64 | 1176.47 | 763.77 | 17.55 | 50.09 | 0.95 | 2005-03 | 31 |
| 2005-04-01 | -7.27 | 903.14 | -200.00 | 3.42 | 662.87 | 161.77 | 946.73 | 107.21 | 943.01 | 523.87 | 15.92 | 35.96 | 0.64 | 2005-04 | 1 |
| 2005-04-02 | 0.85 | 890.90 | -200.00 | 2.53 | 616.20 | 142.37 | 991.70 | 100.08 | 864.26 | 481.61 | 15.49 | 32.21 | 0.55 | 2005-04 | 2 |
| 2005-04-03 | 1.14 | 981.15 | -200.00 | 4.32 | 714.58 | 167.66 | 855.97 | 111.14 | 985.11 | 716.97 | 18.38 | 33.69 | 0.62 | 2005-04 | 3 |
| 2005-04-04 | -11.39 | 1090.40 | -200.00 | 8.44 | 862.13 | 263.25 | 745.05 | 121.84 | 1194.92 | 995.13 | 16.97 | 42.79 | 0.72 | 2005-04 | 4 |
391 rows × 15 columns
labels = {"Day": "Dzień", "RH": "Średnia wartość wilgotności powietrza [%]"}
fig = px.bar(df_date, x="Day",y="RH", color=df_date["RH"],animation_frame=df_date["Month_year"], labels=labels,title="Średnia wilgotność według dni dla wybranego miesiąca")
fig.update_layout(height=800,xaxis_range=(0,32),yaxis_range=(0,df_date["RH"].max()))
fig.show()
Powyższy wykres przedstawia średnią wartość wilgotności powietrza [%]. Dlatego też wykres zaczyna się od 0 dla osi y. Dla powyższej animacji należałoby ustawić także identyczną skalę.
df_date = df_date.reset_index()
x_axis = df_date["Date"]
y_Axis = df_date["RH"]
plt.figure(figsize=(50, 30))
plt.plot(x_axis,y_Axis)
plt.title('Średnia wilgotność',fontsize=30)
plt.xlabel('Dzień',fontsize=30)
plt.ylabel('Średnia wilgotność [%]',fontsize=30)
plt.show()
Powyższy wykres przedstawia wartości wprost z danych. Przy przedstawianiu danych tego typu warto byłoby najpierw usunąć wartości brakujące, ponieważ w tym momencie jest on nieczytelny.
df_date["RH"] = df_date["RH"].replace(-200,np.NaN)
df_date.fillna(value=df_date['RH'].median(), inplace=True)
import seaborn as sns
plt.figure(figsize=(50, 30))
sns.boxplot(x=df_date["RH"],whis=2)
<AxesSubplot:xlabel='RH'>
statistics_RH = df_date["RH"].describe().T
q3 = statistics_RH["75%"]
q1 = statistics_RH["25%"]
iqr = q3 -q1
min_outlier = q1 - 1.5 * iqr
max_outlier = q3 + 1.5 * iqr
mask = (df_date["RH"] < min_outlier) | (df_date["RH"] > max_outlier)
df_date["Outlier"] = mask
x_axis = df_date.index
y_axis = df_date["RH"]
mask = df_date[df_date["Outlier"] == True]
y_outlier = mask["RH"]
x_outlier = mask.index
plt.figure(figsize=(50, 30))
#plt.plot(x_axis,y_axis)
blue_dot = plt.scatter(x_axis, y_axis,color="blue",s=30)
plt.title('Średnia wilgotność dla próbek',fontsize=30)
plt.xlabel('Numer próbki',fontsize=30)
plt.ylabel('Średnia wilgotność [%]',fontsize=30)
red_cross = plt.scatter(x_outlier, y_outlier,color="red",s=500,marker="x")
plt.legend([blue_dot, (red_cross, blue_dot)], ["Wartości 'normalne'", "Obserwacja odstająca"],bbox_to_anchor =(1, 1.10), ncol = 2)
plt.show()
Na poniższym histogramie można zauważyć, że występują wartości brakujące (-200). Rysując drugi histogram założono, że temperatura poniżej -20 stopni nie będzie brana pod uwagę - założono, że we Włoszech ciężko o temperatury poniżej -20 stopni. Można nawet wykluczyć wszystkie pomiary poniże 0 stopni C w ciągu dnia.
date_T = df_date["T"]
plt.figure(figsize=(50, 30))
plt.hist(date_T,50)
plt.title('Histogram zmiennej T (temperatura)',fontsize=30)
plt.xlabel('Temperatura [°C]',fontsize=30)
plt.ylabel('Ilość wystąpień',fontsize=30)
plt.show()
date_T_without_20 = date_T[date_T > -20]
plt.figure(figsize=(50, 30))
plt.hist(date_T_without_20,50)
plt.title('Histogram zmiennej T (temperatura)',fontsize=30)
plt.xlabel('Temperatura [°C]',fontsize=30)
plt.ylabel('Ilość wystąpień',fontsize=30)
plt.show()
Cecha RH i T korelują ze sobą. Wilgotność i temperatura mocno zależą od siebie.
df_corr = df[['T', 'RH']]
corr_matrix = df_corr.corr()
sn.heatmap(corr_matrix, annot=True)
plt.show()